package com.artnology.independence.views.jung;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Point2D;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.collections15.Transformer;

import com.artnology.independence.model.DVNode;

import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.visualization.Layer;
import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.renderers.Renderer;
import edu.uci.ics.jung.visualization.renderers.VertexLabelRenderer;
import edu.uci.ics.jung.visualization.transform.shape.GraphicsDecorator;

public class DynamicSizeVertexRenderer<V, E> implements
		Renderer.VertexLabel<V, E>, Transformer<V, Shape> {
	protected Map<V, Shape> shapes = new HashMap();
	protected RenderContext<V, E> rc;
	static Font boldFont = new Font("Arial", Font.BOLD, 14);

	public DynamicSizeVertexRenderer(RenderContext<V, E> rc) {
		this.rc = rc;
	}

	public Component prepareRenderer(RenderContext<V, E> rc,
			VertexLabelRenderer graphLabelRenderer, Object value,
			boolean isSelected, V vertex) {

		return rc.getVertexLabelRenderer().getVertexLabelRendererComponent(
				rc.getScreenDevice(), value, boldFont, isSelected, vertex);
	}

	public void labelVertex(RenderContext<V, E> rc, Layout<V, E> layout, V v,
			String label) {

		Graph graph = layout.getGraph();
		GraphicsDecorator g = rc.getGraphicsContext();

		Component component = prepareRenderer(rc, rc.getVertexLabelRenderer(),
				label, rc.getPickedVertexState().isPicked(v), v);

		Dimension d = component.getPreferredSize();

		int h_offset = -d.width / 2;
		int v_offset = -d.height / 2;

		Point2D p = (Point2D) layout.transform(v);
		p = rc.getMultiLayerTransformer().transform(Layer.LAYOUT, p);

		int x = (int) p.getX();
		int y = (int) p.getY();

		g.draw(component, rc.getRendererPane(), x + h_offset, y + v_offset,
				d.width, d.height, true);

		Dimension size = component.getPreferredSize();
		Rectangle bounds = new Rectangle(-size.width / 2 - 2,
				-size.height / 2 - 2, size.width + 4, size.height);
		this.shapes.put(v, bounds);
	}

	public Shape transform(V v) {

		Component component = prepareRenderer(this.rc,
				this.rc.getVertexLabelRenderer(), this.rc
						.getVertexLabelTransformer().transform(v), this.rc
						.getPickedVertexState().isPicked(v), v);
		DVNode vertexNode = (DVNode) v;
		Dimension size = component.getPreferredSize();
		return vertexNode.getPaintShape(size.width, size.height);
	}

	public Renderer.VertexLabel.Position getPosition() {

		return Renderer.VertexLabel.Position.CNTR;
	}

	public Renderer.VertexLabel.Positioner getPositioner() {
		return new Renderer.VertexLabel.Positioner() {
			public Renderer.VertexLabel.Position getPosition(float x, float y,
					Dimension d) {
				return Renderer.VertexLabel.Position.CNTR;
			}
		};
	}

	public void setPosition(Renderer.VertexLabel.Position position) {
	}

	public void setPositioner(Renderer.VertexLabel.Positioner positioner) {
	}
}
